#ifndef KEY_HANDLE_H_
#define KEY_HANDLE_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "stdint.h"
#include "mytype.h"

	typedef enum 
	{
		KEY_OPT_PRESSDOWN = 0,	
		KEY_OPT_KEEP,			
		KEY_OPT_RELEASE,		
	} key_opt_mode_type;	
	
	struct key_opt_struct
	{
		uint32_t key_val;
		void (*opt)(key_opt_mode_type mode);
	};

	typedef struct key_opt_struct key_opt_type;

	struct key_api_struct
	{
		void (*key_down_any)(void);
		
		void (*key_keep_any)(void);
		
		const key_opt_type *key_obj;
		
		void (*key_release_any)(void);
		
		void (*key_idle)(void);
	};

	typedef struct key_api_struct key_api_type;

	struct key8_struct
	{
		uint8_t series_space_sv; 
		uint8_t b_locked;		 
		byte_tt unlock_key;		 
		
		uint8_t b_first_key;	 
		uint8_t b_do_none_rls;	 
		uint8_t serial_cnt;		 
		uint16_t found_time_cnt; 
		uint16_t lost_time_cnt;	 
		uint16_t keep_time_cnt;	 
		byte_tt val;			 
		byte_tt edge;			 
		byte_tt found_edge;		 
		byte_tt lost_edge;		 
		uint8_t old;			 
		uint8_t mixed_val;		 
		uint8_t serial_edge;	 
		uint8_t read[3];		 
		const key_api_type *api; 
	};

	typedef struct key8_struct key8_type;

	void key8_st_sample(key8_type *key, uint8_t key_read);

	void key8_st_handle(key8_type *key, uint8_t time_pulse);

	struct key16_struct
	{
		uint8_t series_space_sv; 
		uint8_t b_locked;		 
		word_tt unlock_key;		 
		
		uint8_t b_first_key;	 
		uint8_t b_do_none_rls;	 
		uint8_t serial_cnt;		 
		uint16_t found_time_cnt; 
		uint16_t lost_time_cnt;	 
		uint16_t keep_time_cnt;	 
		word_tt val;			 
		word_tt edge;			 
		word_tt found_edge;		 
		word_tt lost_edge;		 
		uint16_t old;			 
		uint16_t mixed_val;		 
		uint16_t serial_edge;	 
		uint16_t read[3];		 
		const key_api_type *api; 
	};

	typedef struct key16_struct key16_type;

	void key16_st_sample(key16_type *key, uint16_t key_read);

	void key16_st_handle(key16_type *key, uint8_t time_pulse);

	struct key32_struct
	{
		uint8_t series_space_sv; 
		uint8_t b_locked;		 
		dword_tt unlock_key;	 
		
		uint8_t b_first_key;	 
		uint8_t b_do_none_rls;	 
		uint8_t serial_cnt;		 
		uint16_t found_time_cnt; 
		uint16_t lost_time_cnt;	 
		uint16_t keep_time_cnt;	 
		dword_tt val;			 
		dword_tt edge;			 
		dword_tt found_edge;	 
		dword_tt lost_edge;		 
		uint32_t old;			 
		uint32_t mixed_val;		 
		uint32_t serial_edge;	 
		uint32_t read[3];		 
		const key_api_type *api; 
	};

	typedef struct key32_struct key32_type;

	void key32_st_handle(key32_type *key, uint8_t time_pulse);

	void key32_st_sample(key32_type *key, uint32_t key_read);

	struct key_click_struct
	{
		uint8_t space_sv;		 
		uint8_t serial_sv;		 
								 
		uint8_t serial_cnt;		 
		uint8_t key_old;		 
		uint8_t multi_click_out; 
		uint8_t edge_found;		 
		uint8_t edge_lost;		 
		uint16_t st_keep_cnt;
	};

	typedef struct key_click_struct key_click_type;

	uint8_t key_click_handle(key_click_type *obj, uint8_t key_now, uint8_t pulse);

	struct rot_key_struct
	{
		uint8_t b_clock;			  
		uint8_t b_unti_clock;		  
		uint16_t clock_interval_rl;	  
		uint16_t clock_none_time_cnt; 
		uint16_t high_spd_pulse_cnt;
		uint8_t a_st;
		uint8_t a_old;
		uint8_t b_st;
		uint8_t b_old;
		uint8_t spd_st;				 
		uint16_t clock_interval_val; 
	};
	typedef struct rot_key_struct rot_key_type;

	void rot_key_handle(rot_key_type *key, uint8_t a, uint8_t b);
    void rot_key_rot_handle(rot_key_type *key, uint8_t rot); 

	void rot_ekey_handle(rot_key_type *key, uint8_t a, uint8_t b);

	uint8_t rot_key_spd_tm_check(rot_key_type *key, const uint16_t *spd_tm);
	
    extern const uint16_t rot_key_spd_tm4[8];
    extern const uint16_t rot_key_spd_tm2[8];
    extern const uint16_t rot_key_spd_tm1[8];
    extern const ii16 rkey_inc_tabx_h[9];
    extern const ii16 rkey_inc_tabx_m[9];
    extern const ii16 rkey_inc_tabx_l[9];

	uint8_t rot_key_spd_simp_check(rot_key_type *key, ii16 tm_min, ii16 tm_max);
	
#ifdef __cplusplus
}
#endif

#endif 
